/***************************************************************************
 *   Copyright (C) 2007 by Ivan Vasić                        *
 *   ivasic@gmail.com                                *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef EXCEPTION_H
#define EXCEPTION_H

#include <QObject>
#include <QString>
#include <QMap>

/**
 * @class Exception
 * @brief Bazna klasa izuzetak.
 * 
 * @author Ivan Vasić <ivasic@gmail.com>
*/

class Exception : public QObject
{
		Q_OBJECT
				
	public:
		
		/**
		 * @enum ExceptionType
		 * @brief Tip izuzetka.
		 * 
		 * Tri tipa izuzetka: Normal, Critical i Fatal.
		 */
		enum ExceptionType
		{
			Normal,
			Critical,
			Fatal
		};

		/**
		 * @brief Default konstruktor
		 * 
		 * Kreira prazan Exception objekat
		 */
		Exception();

		/**
		 * @brief Overloaded konstruktor
		 * @param msg - Inicijalizuje m_message. Poruka izuzetka.
		 * @param type - Tip izuzetka.
		 */
		Exception(const QString& msg, ExceptionType type);


		/**
		 * @brief Overloaded konstruktor
		 * @param msg - Inicijalizuje m_message. Poruka greške.  
		 * @param type - Tip izuzetka.
		 * @param filename - Inicijalizuje m_filename. Ime fajla gde se greška desila.
		 * @param methodName - Inicijalizuje m_methodName. Ime funkcije u kojoj se desila greška.
		 * @param lineNr - Inicijalizuje m_lineNumber. Linija u kodu gde se desila greška
		 * @param innerException - Inicijalizuje m_innerException.
		 */
		Exception(const QString& msg, ExceptionType type, const QString& filename = QString::null, const QString& methodName = QString::null, int lineNr = 0, Exception* innerException = 0);

		/**
		 * @brief Copy constructor.
		 * @param ex Objekat za kopiranje (Exception)
		 */
		Exception(const Exception& ex);

		///Desktruktor
		~Exception();


		/// Operator =
		Exception& operator=(const Exception& ex);


		/*  GET  */

		///Vraća poruku o grešci
		const QString& getMessage() const { return m_message; }
		
		///Vraća tip izuzetka
		ExceptionType getType() const { return m_type; }

		///Vraća ime fajla gde se greška desila.
		const QString& getFilename() const { return m_filename; }

		///Vraća ime funkcije u kojoj se desila greška.
		const QString& getMethod() const { return m_methodName; }

		///Vraća mapu argumenata funkcije u kojoj se desila greška.
		const QMap<QString, QString>& getArguments() const { return m_arguments; }

		///Vraća linija u kodu gde se desila greška
		const int getLineNumber() const { return m_lineNumber; }

		///Vraća pointer na unutrašnju grešku.
		const Exception* getInnerException() const { return m_innerException; }


		///Ispisuje debug info
		const QString debug() const;
		
		///Vraća backtrace
		QString getBacktrace() const;


		/*  SET  */

		///Postavlja poruku o grešci
		void setMessage(const QString& val) { m_message = val; }

		///Postavlja ime fajla gde se greška dogodila
		void setFilename(const QString& val) { m_filename = val; }

		///Postavlja ime funkcije gde se greška dogodila
		void setMethodName(const QString& val) { m_methodName = val; }

		///Postavlja broj linije u kodu gde se greška dogodila
		void setLineNumber(int val) { m_lineNumber = val; }

		///Postavlja pointer na unutrašnju grešku
		void setInnerException(Exception* val) { m_innerException = val; }

		///Postavlja tip izuzetka.
		void setType(const ExceptionType& val) { m_type = val; }
		
	private:
		
		/**
		 * @brief Vraća string reprezentaciju tipa izuzetka.
		 * @param type - Tip izuzetka
		 * @see ExceptionType
		 */
		QString typeToString(ExceptionType type) const;
		

	protected:

		///Poruka greške.
		QString m_message;
		
		///Tip izuzetka. @see ExceptionType
		ExceptionType m_type;

		///Ime fajla gde se greška desila
		QString m_filename;

		///Ime funkcije u kojoj se desila greška
		QString m_methodName;

		///Argumenti funkcije u kojoj se desila greška. Prvi parametar predstavlja ime argumenta, drugi parametar predstavlja vrednost argumenta
		QMap<QString, QString> m_arguments;

		///Linija u kodu gde se desila greška
		int m_lineNumber;

		///Unutrašnja greška. Greška koja je prethodila trenutnoj.
		Exception* m_innerException;
};

#endif
